package com.hmy.finance.job.core;

import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.google.gson.Gson;
import com.hmy.finance.common.properties.ReceivableInventoryOverdueRule;
import com.hmy.finance.dal.po.DeviceRentalRecordPo;
import com.hmy.finance.dal.po.json.ContractExtensionInfoJson;
import com.hmy.finance.service.core.IDeviceRentalRecordService;
import com.hmy.finance.service.core.dto.DailyInvoiceGenerationJobDto;
import com.hmy.finance.service.core.impl.FinancialCoreDataServiceImpl;
import com.xxl.job.core.handler.annotation.XxlJob;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.time.LocalDate;
import java.util.List;
import java.util.Objects;

@Slf4j
@Component
public class DailyFeeBillGenerationJobHandler {
    /**
     * 设备租赁记录服务
     */
    private final IDeviceRentalRecordService deviceRentalRecordService;

    private final FinancialCoreDataServiceImpl financialCoreDataService;
    /**
     * 应收应付逾期规则
     */

    private final ReceivableInventoryOverdueRule overdueRule;

    public DailyFeeBillGenerationJobHandler(IDeviceRentalRecordService deviceRentalRecordService, FinancialCoreDataServiceImpl financialCoreDataService, ReceivableInventoryOverdueRule overdueRule) {
        this.deviceRentalRecordService = deviceRentalRecordService;
        this.financialCoreDataService = financialCoreDataService;
        this.overdueRule = overdueRule;
    }

    @Scheduled(cron = "0 40 23 * * ?")
    public void startJob() {
        this.generateDailyInvoiceBill(null, null, null);
    }

    /**
     * 生成每日费用流水
     */
    @XxlJob("financial_generateDailyInvoiceBill")
//    @Async
    public void generateDailyInvoiceBill(LocalDate startDate, LocalDate endDate, Long contractId) {
        log.info("[处理时间:{}]-开始生成每日费用流水,处理数据范围:{}", DateUtil.now(), Objects.nonNull(startDate) && Objects.nonNull(endDate) ? startDate + "至" + endDate : DateUtil.today());
        if (Objects.isNull(startDate)) {
            startDate = LocalDate.now();
        }
        if (Objects.isNull(endDate)) {
            endDate = LocalDate.now();
        }
        //通过deviceRentalRecordService，查询所有在租设备及今日退租的设备的合同信息
        List<String> contractExtensionInfoJsonList = deviceRentalRecordService.queryAllRentingDeviceContract(startDate, endDate, contractId);
        log.info("[处理时间:{}]-查询所有在租设备及今日退租的设备的合同信息，共{}条", DateUtil.now(), contractExtensionInfoJsonList.size());
        //遍历合同信息，生成每日费用流水
        for (String contractExtensionInfoJson : contractExtensionInfoJsonList) {
            //生成每日费用流水
            this.handleGenerateDailyInvoice(contractExtensionInfoJson, startDate, endDate);
        }
        log.info("[处理时间:{}]-结束生成每日费用流水", DateUtil.now());
    }

    public void handleGenerateDailyInvoice(String contractExtensionInfoJson, LocalDate startDate, LocalDate endDate) {
        log.info("[处理时间:{}]-开始处理生成每日费用流水，合同信息：{}", DateUtil.now(), contractExtensionInfoJson);
        int loop = 1;
        if (Objects.nonNull(startDate) && Objects.nonNull(endDate)) {
            loop = (int) (endDate.toEpochDay() - startDate.toEpochDay() + 1);
        }
        Gson gson = new Gson();
        for (int i = 0; i < loop; i++) {
            log.info("[处理时间:{}]-开始生成每日费用流水，合同信息：{}", DateUtil.now(), contractExtensionInfoJson);
            DailyInvoiceGenerationJobDto dto = DailyInvoiceGenerationJobDto.buildDailyInvoiceGenerationJobDto(gson.fromJson(contractExtensionInfoJson, ContractExtensionInfoJson.class), overdueRule, startDate, endDate);
            List<DeviceRentalRecordPo> list = deviceRentalRecordService.list(Wrappers.lambdaQuery(DeviceRentalRecordPo.class).eq(DeviceRentalRecordPo::getContractId, dto.getContractExtensionInfoJson().getContractId()));
            if (!list.isEmpty()) {
                dto.setCustomerExtensionInfoJson(list.get(0).getCustomerExtensionInfo());
                dto.setOrderExtensionInfoJson(list.get(0).getOrderExtensionInfo());
            }
            //设置处理日期
            dto.setHandleDate(dto.getStartDate().plusDays(i));
            //超出当前日期，结束处理
            if (dto.getHandleDate().isAfter(LocalDate.now())) {
                break;
            }
            //超出预设处理日期范围，结束处理
            if (Objects.nonNull(dto.getEndDate()) && dto.getHandleDate().isAfter(dto.getEndDate())) {
                break;
            }
            log.info("[处理时间:{}]-生成每日费用流水，DTO信息是：{}", DateUtil.now(), dto);
            //处理生成每日费用流水
            financialCoreDataService.handleGenerateDailyBill(dto);
        }

        log.info("[处理时间:{}]-完成处理生成每日费用流水，合同信息：{}", DateUtil.now(), contractExtensionInfoJson);
    }
}
